﻿using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace CHIP8Emulator {
    public partial class LogControl : UserControl {
        public delegate void AddLogRow(NotifyLogMessageEventArgs args);
        public AddLogRow AddLogRowDelegate;

        public LogControl() {
            AddLogRowDelegate = new AddLogRow(AddLogRowMethod);
            InitializeComponent();
        }
        
        public void InitBy(Logger logger) {}

        public Logger CreateLogger() {
            NotificationLogger logger = new NotificationLogger();
            logger.OnUpdate += (sender, args) => { if (InvokeRequired) Invoke(AddLogRowDelegate, args); else AddLogRowMethod(args); };
            return logger;
        }

        private void AddLogRowMethod(NotifyLogMessageEventArgs args){
            dataGridView1.Rows.Insert(0, dataGridView1.RowCount, args.Timestamp, args.MessageType, args.Message);
        }
    }


    public class NotificationLogger : Logger {
        /*
         * Instead of logging, notifies subscribers with log messages.
         */

        public event NotifyLogMessageEventHandler OnUpdate;

        public override void Log(LogMessageType messageType, string format, params object[] args) {
            if (OnUpdate != null)
                OnUpdate(this, new NotifyLogMessageEventArgs(DateTime.Now, messageType, string.Format(format, args)));
        }
    }

    public delegate void NotifyLogMessageEventHandler(object sender, NotifyLogMessageEventArgs args);

    public class NotifyLogMessageEventArgs : EventArgs {
        private readonly DateTime _timestamp;
        private readonly LogMessageType _messageType;
        private readonly string _message;

        public NotifyLogMessageEventArgs(DateTime timestamp, LogMessageType messageType, string message) {
            _timestamp = timestamp;
            _messageType = messageType;
            _message = message;
        }

        public DateTime Timestamp {
            get { return _timestamp; }
        }

        public LogMessageType MessageType {
            get { return _messageType; }
        }

        public string Message {
            get { return _message; }
        }
    }
}